/**
 * Title:		KFrogReal.java
 * Description: This class is used to represent real data type. 
 * 
 * @version		1.0 May 2009
 * @author		Rami Habas
 */

package kfrog.type;

public class KFrogReal extends KFrogDataType {

	/** variable value */
	private double variable;

	/**
     * Constructor used to instantiate a variable of real type
     * 
     * @param variable   The initial value
     */
	public KFrogReal(double variable) {
		super();
		this.variable = variable;
		init = true;
	}

	/**
     * Default Constructor instantiates a variable with a default value of 0.
     */
	public KFrogReal() {
		this(0);
		init = false;
	}
	
	/**
     * Useful method that returns the double value of the given KFrogDataType
     * variable
     * 
     * @param b   KFrogDataType variable
     */
	public static double realValue(KFrogDataType b) {
		b.initCheck();

		if (b instanceof KFrogReal)
			return ((KFrogReal)b).variable;

		if (b instanceof KFrogDecimal)
			return (double)((KFrogDecimal)b).getVariable();

		throw new RuntimeException("Cannot cast to real value");
	}

	/** real type copy method */
	public KFrogDataType copy() {
		initCheck();
		return new KFrogReal(variable);
	}

	/** instantiate a new real type */
	public KFrogDataType newType() {
		return new KFrogReal();
	}

	public String typeName() {
		return "real";
	}

	/** get the real value as String */
	public String getValue() {
		initCheck();
		return String.valueOf(variable);
	}

	/** get the real value as a double */
	public double getVariable() {
		initCheck();
		return variable;
	}

	public KFrogDataType plus(KFrogDataType b) {
		initCheck();

		return new KFrogReal(variable + realValue(b));
	}

	public KFrogDataType minus(KFrogDataType b) {
		initCheck();

		return new KFrogReal(variable - realValue(b));
	}

	public KFrogDataType times(KFrogDataType b) {
		initCheck();

		return new KFrogReal(variable * realValue(b));
	}

	public KFrogDataType divide(KFrogDataType b) {
		initCheck();

		return new KFrogReal(variable/ realValue(b));
	}

	public KFrogDataType modulo(KFrogDataType b) {
		initCheck();

		return new KFrogReal(variable % realValue(b));
	}

	public KFrogDataType prefixIncrement() {
		variableCheck();
		initCheck();
		return new KFrogReal(++variable);
	}

	public KFrogDataType postfixIncrement() {
		variableCheck();
		initCheck();
		return new KFrogReal(variable++);
	}

	public KFrogDataType prefixDecrement() {
		variableCheck();
		initCheck();
		return new KFrogReal(--variable);
	}

	public KFrogDataType postfixDecrement() {
		variableCheck();
		initCheck();
		return new KFrogReal(variable--);
	}

	/**
     * Perform the assignment a=b where a is this instance. Note that this can
     * also serve as an initialization so init=true.
     * 
     * @param b   KFrogDataType variable
     */
	public KFrogDataType assign(KFrogDataType b) {
		variableCheck();
		variable = realValue(b);
		init = true;
		return this;
	}

	public KFrogDataType isEqual(KFrogDataType b) {
		initCheck();

		return new KFrogLogical((realValue(b) == variable));
	}

	public KFrogDataType plusAssign(KFrogDataType b) {
		variableCheck();
		initCheck();
		variable+= realValue(b);
		return this;
	}

	public KFrogDataType minusAssign(KFrogDataType b) {
		variableCheck();
		initCheck();
		variable-= realValue(b);
		return this;
	}

	public KFrogDataType timesAssign(KFrogDataType b) {
		variableCheck();
		initCheck();
		variable*= realValue(b);
		return this;
	}

	public KFrogDataType divideAssign(KFrogDataType b) {
		variableCheck();
		initCheck();
		variable/= realValue(b);
		return this;
	}

	public KFrogDataType moduloAssign(KFrogDataType b) {
		variableCheck();
		initCheck();
		variable%= realValue(b);
		return this;
	}

	public KFrogDataType greaterThan(KFrogDataType b) {
		initCheck();

		return new KFrogLogical(variable > realValue(b));

	}

	public KFrogDataType greaterThanOrEqual(KFrogDataType b) {
		initCheck();

		return new KFrogLogical(variable >= realValue(b));

	}

	public KFrogDataType lessThan(KFrogDataType b) {
		initCheck();

		return new KFrogLogical(variable < realValue(b));
	}

	public KFrogDataType lessThanOrEqual(KFrogDataType b) {
		initCheck();

		return new KFrogLogical(variable <= realValue(b));
	}

	public KFrogDataType notEqual(KFrogDataType b) {
		initCheck();
		return new KFrogLogical(realValue(b) != variable);
	}

	public KFrogDataType unaryPlus() {
		initCheck();
		return new KFrogReal(+variable);
	}

	public KFrogDataType unaryMinus() {
		initCheck();
		return new KFrogReal(-variable);
	}
}
